无题 匡思进 2025-11-29 2025-11-29 IOC(控制反转)和DI(依赖注入)是spring中的重要组成部分,下面是个人的一些理解,不代表官方。
1、IOC是什么?
IOC:全名是Inversion of Controller 中文解释是控制反转,不是什么技术,是一种设计思想。在java开发中IOC意味着你设计好的对象交给容器控制,而不是传统的在你对象内部直接控制。如何理解好IOC那?理解IOC的关键是要明确:“谁控制谁”、“控制什么”、为何是反转(有反转就应该有正转)哪些方面反转了,我们来分析一下:
1)谁控制谁,控制什么:传统的java SE程序设计,我们直接在对象内部new进行创建对象,是程序主动去创建对象,而IOC有专门的容器来创建这些对象,即由IOC容器来控制对象的创建;谁控制谁?当然是IOC容器控制对象,控制什么?主要是控制外部资源的获取(不只是对象包括比如文件等)。
2)为何是反转,那方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中直接获取依赖对象,也就是正转;而反转是由容器来帮忙创建和注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取反转了。
用图例说明一下,传统程序设计如下图1,都是主动去创建相关对象然后再组合起来:
![[be5f27613f427f80e7aa2a6e8ced0f93_MD5.jpg]]
当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图2所示
![[5b3f9c423e94b7506e57c9832309aadb_MD5.jpg]]
2、IOC(控制反转)做什么用?
IOC不是一种技术,是一种设计思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由程序内部主动创建对象依赖,从而导致类与类之间高耦合,难于测试;有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器注入组合对象,所以对象和对象之间是松耦合的,这样利于测试,也利于功能复用,更重要的是使得程序的整个体系结构变的非常灵活。
其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。 IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
3、DI是什么? DI:Dependency Injection ,即依赖注入:是组件之间依赖关系由容器在运行期决定,形象的说,由容器动态的将某个依赖关系注入到组件之中。
4、DI(依赖注入)有什么用
依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
理解DI的关键:谁依赖谁,为什么需要依赖,谁注入谁,注入了什么?
1)谁依赖谁:当然是应用程序依赖IOC容器
2)为什么需要依赖:应用程序需要IOC容器来提供对象需要的外部资源
3)谁注入谁:IOC容器注入应用程序的某个对象,应用程序依赖的对象
4)注入了什么:注入某个对象依赖的外部资源(包括对象,资源,常来数据)
IoC和DI什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
5、怎么用?
整体如图:
![[c9b4f5660d31f3fe12e6fcdafc157127_MD5.png]]
代码如下:
1、Servelt转ApplicationContext:(1)获取applicationContext上下文(2)初始化handlerMapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 package com.zmc.spring.framework.context; import com.zmc.spring.framework.annotation.MCAutowried;import com.zmc.spring.framework.annotation.MCController;import com.zmc.spring.framework.annotation.MCService;import com.zmc.spring.framework.beans.MCBeanWrapper;import com.zmc.spring.framework.beans.config.MCBeanDefinition;import com.zmc.spring.framework.beans.support.MCBeanDefinitionReader;import com.zmc.spring.framework.beans.support.MCDefaultListableBeanFactory;import com.zmc.spring.framework.core.MCBeanFactory; import java.lang.reflect.Field;import java.util.HashMap;import java.util.List;import java.util.Map; public class MCApplicationContext implements MCBeanFactory { private MCDefaultListableBeanFactory registry = new MCDefaultListableBeanFactory (); private Map<String,MCBeanWrapper> factoryBeanInstanceCache = new HashMap <String, MCBeanWrapper>(); private Map<String,Object> factoryBeanObjectCache = new HashMap <String, Object>(); private MCBeanDefinitionReader reader; public MCApplicationContext (String... configLocations) { reader = new MCBeanDefinitionReader (configLocations); try { List<MCBeanDefinition> beanDefinitions = reader.loadBeanDefinitions(); this .registry.addBeanDefinitionMap(beanDefinitions); doLoadInstance(); } catch (Exception e) { e.printStackTrace(); } } private void doLoadInstance () { for (Map.Entry<String,MCBeanDefinition> entry : this .registry.beanDefinitionMap.entrySet()){ String beanName = entry.getKey(); if (!entry.getValue().isLazyInit()){ getBean(beanName); } } } public Object getBean (Class className) { return getBean(className.getName()); } public Object getBean (String beanName) { MCBeanDefinition beanDefinition = registry.beanDefinitionMap.get(beanName); if (beanDefinition == null ){ return null ; } Object instance = instantiateBean(beanName,beanDefinition); MCBeanWrapper beanWrapper = new MCBeanWrapper (instance); populateBean(beanName,beanDefinition,beanWrapper); this .factoryBeanInstanceCache.put(beanName,beanWrapper); return beanWrapper.getWrapperInstance(); } private Object instantiateBean (String beanName,MCBeanDefinition beanDefinition) { String className = beanDefinition.getBeanClassName(); Object instance = null ; try { Class<?> clazz = Class.forName(className); instance = clazz.newInstance(); this .factoryBeanObjectCache.put(beanName,instance); } catch (Exception e) { e.printStackTrace(); } return instance; } private void populateBean (String beanName,MCBeanDefinition beanDefinition,MCBeanWrapper beanWrapper) { Object instance = beanWrapper.getWrapperInstance(); Class<?> clazz = beanWrapper.getWrapperClass(); if (!(clazz.isAnnotationPresent(MCController.class) || clazz.isAnnotationPresent(MCService.class))){ return ; } for (Field filed : clazz.getDeclaredFields()){ if (!filed.isAnnotationPresent(MCAutowried.class)){ continue ; } MCAutowried autowried= filed.getAnnotation(MCAutowried.class); String autowriedBeanName = autowried.value().trim(); if ("" .equals(autowriedBeanName)){ autowriedBeanName = filed.getType().getName(); } filed.setAccessible(true ); try { if (this .factoryBeanInstanceCache.get(autowriedBeanName) == null ){ continue ; } filed.set(instance,this .factoryBeanInstanceCache.get(autowriedBeanName).getWrapperInstance()); } catch (IllegalAccessException e) { e.printStackTrace(); } } } public int getBeanDefinitionCount () { return this .registry.beanDefinitionMap.size(); } public String[] getBeanDefinitionNames(){ return this .registry.beanDefinitionMap.keySet().toArray(new String [0 ]); } }
2、ApplicationContext 上下文对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 package com.zmc.spring.framework.context; import com.zmc.spring.framework.annotation.MCAutowried;import com.zmc.spring.framework.annotation.MCController;import com.zmc.spring.framework.annotation.MCService;import com.zmc.spring.framework.beans.MCBeanWrapper;import com.zmc.spring.framework.beans.config.MCBeanDefinition;import com.zmc.spring.framework.beans.support.MCBeanDefinitionReader;import com.zmc.spring.framework.beans.support.MCDefaultListableBeanFactory;import com.zmc.spring.framework.core.MCBeanFactory; import java.lang.reflect.Field;import java.util.HashMap;import java.util.List;import java.util.Map; public class MCApplicationContext implements MCBeanFactory { private MCDefaultListableBeanFactory registry = new MCDefaultListableBeanFactory (); private Map<String,MCBeanWrapper> factoryBeanInstanceCache = new HashMap <String, MCBeanWrapper>(); private Map<String,Object> factoryBeanObjectCache = new HashMap <String, Object>(); private MCBeanDefinitionReader reader; public MCApplicationContext (String... configLocations) { reader = new MCBeanDefinitionReader (configLocations); try { List<MCBeanDefinition> beanDefinitions = reader.loadBeanDefinitions(); this .registry.addBeanDefinitionMap(beanDefinitions); doLoadInstance(); } catch (Exception e) { e.printStackTrace(); } } private void doLoadInstance () { for (Map.Entry<String,MCBeanDefinition> entry : this .registry.beanDefinitionMap.entrySet()){ String beanName = entry.getKey(); if (!entry.getValue().isLazyInit()){ getBean(beanName); } } } public Object getBean (Class className) { return getBean(className.getName()); } public Object getBean (String beanName) { MCBeanDefinition beanDefinition = registry.beanDefinitionMap.get(beanName); if (beanDefinition == null ){ return null ; } Object instance = instantiateBean(beanName,beanDefinition); MCBeanWrapper beanWrapper = new MCBeanWrapper (instance); populateBean(beanName,beanDefinition,beanWrapper); this .factoryBeanInstanceCache.put(beanName,beanWrapper); return beanWrapper.getWrapperInstance(); } private Object instantiateBean (String beanName,MCBeanDefinition beanDefinition) { String className = beanDefinition.getBeanClassName(); Object instance = null ; try { Class<?> clazz = Class.forName(className); instance = clazz.newInstance(); this .factoryBeanObjectCache.put(beanName,instance); } catch (Exception e) { e.printStackTrace(); } return instance; } private void populateBean (String beanName,MCBeanDefinition beanDefinition,MCBeanWrapper beanWrapper) { Object instance = beanWrapper.getWrapperInstance(); Class<?> clazz = beanWrapper.getWrapperClass(); if (!(clazz.isAnnotationPresent(MCController.class) || clazz.isAnnotationPresent(MCService.class))){ return ; } for (Field filed : clazz.getDeclaredFields()){ if (!filed.isAnnotationPresent(MCAutowried.class)){ continue ; } MCAutowried autowried= filed.getAnnotation(MCAutowried.class); String autowriedBeanName = autowried.value().trim(); if ("" .equals(autowriedBeanName)){ autowriedBeanName = filed.getType().getName(); } filed.setAccessible(true ); try { if (this .factoryBeanInstanceCache.get(autowriedBeanName) == null ){ continue ; } filed.set(instance,this .factoryBeanInstanceCache.get(autowriedBeanName).getWrapperInstance()); } catch (IllegalAccessException e) { e.printStackTrace(); } } } public int getBeanDefinitionCount () { return this .registry.beanDefinitionMap.size(); } public String[] getBeanDefinitionNames(){ return this .registry.beanDefinitionMap.keySet().toArray(new String [0 ]); } }
参考:浅谈对Spring IOC以及DI的理解_luoyepiaoxue2014的博客-CSDN博客_ioc和di
本文转自 https://blog.csdn.net/zhang2383906154/article/details/121331773?ops_request_misc=%257B%2522request%255Fid%2522%253A%25224e5f7713ece11e4c78889286db411330%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=4e5f7713ece11e4c78889286db411330&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-121331773-null-null.142^v102^pc_search_result_base5&utm_term=ioc%E5%92%8Cdi&spm=1018.2226.3001.4187 ,如有侵权,请联系删除。